﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace TCCCompiler
{
    class Token
    {
        public string name;
        public string statementType;
        public string tokenType;
        public int index;
        string[] m_TypesOfStatements;
        string[] m_TypesOfTokens;
        string[] m_DataTypesOrStructures;
        string[] m_ReservedWords;
        string[] m_Operators;
        string[] m_Functions;
        public Regex m_Identifiers;
        public Regex m_CharacterConstants;
        public Regex m_IntegerConstants;

        ////PROPERTIES
        //public string StatementType
        //{
        //    get
        //    {
        //        statementType = AssignStatementType();
        //        return statementType;
        //    }
        //    set 
        //    { 
        //        statementType = value;
        //        //StatementType = value;
        //    }
        //}
        //public string TokenType
        //{
        //    get
        //    {
        //        tokenType = AssignTokenType(statementType);
        //        return tokenType;
        //    }
        //    //set { tokenType = value; }
        //}

        //CONSTRUCTOR
        public Token(string Name, int Index)
        {
            index = Index;
            name = Name;
            Initialize();
            AssignValues();
            //tokenType = AssignTokenType();
        }

        //METHODS
        void AssignValues()
        {
            statementType = AssignStatementType();
            tokenType = AssignTokenType(statementType);
        }
        string AssignTokenType(string TokenTypeStr)
        {
            if (Contains(m_TypesOfStatements, TokenTypeStr) && index == 0)
                return m_TypesOfTokens[1];//RW
            else if (Contains(m_ReservedWords, name) || Contains(m_DataTypesOrStructures, name) || Contains(m_Functions, name))
                return m_TypesOfTokens[1]; // RW bardo !!
            else if (m_Identifiers.IsMatch(name))
                return m_TypesOfTokens[0]; //Identifier
            else if (m_CharacterConstants.IsMatch(name) || m_IntegerConstants.IsMatch(name))
                return m_TypesOfTokens[6]; // Char or Int Constant
            else if (Contains(m_Operators, name))
                return m_TypesOfTokens[5]; // Operator
            return "Blah_Blah_Type";
        }

        string AssignStatementType()
        {
            if (Contains(m_DataTypesOrStructures, name) && index == 0)
                return m_TypesOfStatements[1]; // Declaration st
            else if ((name == m_ReservedWords[3] || name == m_ReservedWords[4] || name == m_ReservedWords[5] || name == m_ReservedWords[11] || name == m_ReservedWords[12]) && index == 0)
                return m_TypesOfStatements[5]; // For st
            else if ((name == m_ReservedWords[6] || name == m_ReservedWords[7] || name == m_ReservedWords[8] || name == m_ReservedWords[13] || name == m_ReservedWords[14]) && index == 0)
                return m_TypesOfStatements[4]; // while st
            else if (name == m_ReservedWords[2] && index == 0)
                return m_TypesOfStatements[0]; // atomic
            else if ((name == m_ReservedWords[0] || name == m_ReservedWords[1]) && index == 0)
                return m_TypesOfStatements[3]; //If
            else if (name == m_ReservedWords[9] && index == 0)
                return m_TypesOfStatements[6]; // Lock
            else if (name == m_ReservedWords[10] && index == 0)
                return m_TypesOfStatements[7]; // Unlock
            ///////////////////
            /// Assignment st.  ///
            ///////////////////
            return "Blah_Blah";

        }
        void Initialize()
        {
            m_Functions = new string[2] { "add" , "remove" };
            m_Identifiers = new Regex(@"^[a-zA-Z][0-9a-zA-Z]*");
            m_IntegerConstants = new Regex(@"[-]?[0-9]+(\.[0-9]+)?(E[-]?[0-9]+(\.[0-9]+)?)?");
            //m_CharacterConstants = new Regex("^[\"].+[\"]+$");
            //m_CharacterConstants = new Regex("\'(\w)\'");
            m_CharacterConstants = new Regex("\'[a-zA-Z0-9]\'");
            m_TypesOfStatements = new string[8] {"Atomic_Block","Declaration_Statement","Assign_Statement",
                "If_Statement","While_Statement","For_Statement","Lock_Block","Unlock"};
            //0 - Atomic
            //1 - Declaration
            //2 - Assign
            //3 - iInitialization
            //4 - If (Else)
            //5 - While
            //6 - For
            //7 - Lock
            //8 - Unlock
            m_TypesOfTokens = new string[7] { "Identifier", "Reserved_Word", "Expression", "Term", "Factor", "Operator", "Constant" };
            //0 - Identifier
            //1 - RW
            //2 - Exp
            //3 - Term
            //4 - Factor
            //5 - Op
            //6 - Constant
            m_DataTypesOrStructures = new string[4] { "int", "char", /*"int[]", "char[]",*/ "Hashtable", "Class" };
            m_ReservedWords = new string[16] { "if", "else", "atomic", "for", "t_for", "t_for_n", "while", "t_while","t_while_n",
                "lock", "unlock", "t_for_unordered", "t_for_n_unordered", "t_while_unordered", "t_while_n_unordered", "new" };
            m_Operators = new string[27] {"+=","-=","*=","/=","&&","||","++","--", "<=", ">=", "!=", "==", "+", "-", "*", "/", "%", "=", "<", ">", ";", "(", ")", "[", "]" , "." , ","};
        }
        
        bool Contains(string[] stringArray, string str)
        {
            for (int i = 0; i < stringArray.Length; i++)
            {
                if (stringArray[i].Equals(str))
                    return true;
            }
            return false;
        }


    }
}
